/*
 * Copyright (C) 2025 ameise <ameise.wang@gmail.com> - All Rights Reserved
 *
 * This file is part of e3ds.
 *
 * e3ds is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * e3ds is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with e3ds. If not, see <https://www.gnu.org/licenses/>.
 */

package heap

import (
	"gitee.com/ameise84/e3ds/heap/compare"
	"github.com/modern-go/reflect2"
	"sync"
	"sync/atomic"
)

var gPoolMap sync.Map

type entity[T1 Integer, T2 compare.Ordered[T2]] struct {
	id    T1
	index int
	ctx   T2
}

type poolBuilder[T1 Integer, T2 compare.Ordered[T2]] struct {
	p      *sync.Pool
	gIndex atomic.Uint64
	mu     sync.Mutex
	once   sync.Once
}

func newPool[T1 Integer, T2 compare.Ordered[T2]]() *sync.Pool {
	var t1 = new(T1)
	var t2 = new(T2)
	typ1 := reflect2.TypeOf(t1).String()
	typ2 := reflect2.TypeOf(t2).String()
	p, _ := gPoolMap.LoadOrStore(typ1+typ2, &poolBuilder[T1, T2]{})
	pb := p.(*poolBuilder[T1, T2])
	pb.once.Do(func() {
		pb.p = &sync.Pool{
			New: func() any {
				return &entity[T1, T2]{
					id: T1(pb.gIndex.Add(1)),
				}
			},
		}
	})
	return pb.p
}
